package com.lznAdmin.security.config;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.lznAdmin.base.common.util.JwtUtil;
import com.lznAdmin.system.entity.SysUser;
import com.lznAdmin.system.service.SysUserService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.web.servlet.HandlerExceptionResolver;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @program: lzn-manage-parent
 * @description: 过滤器-识别jwt
 * @author: lzn
 * @create: 2021-10-13 00:04
 **/
@Slf4j
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {
    // Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private CustomUserDetailsService customUserDetailsService;
    @Autowired
    @Qualifier("handlerExceptionResolver")
    HandlerExceptionResolver resolver;
    @Autowired
    private SysUserService sysUserService;


    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {

        String jwt = request.getHeader(jwtUtil.getHeader());
        logger.info(jwt);
        if (StrUtil.isBlankOrUndefined(jwt)) {
            chain.doFilter(request, response);
            return;
        }

        Claims claim = jwtUtil.getClaimByToken(jwt);
        String username = claim.getSubject();
        if (claim == null) {
            resolver.resolveException(request, response, null, new JwtException("token异常"));
            return;
        }
        if (jwtUtil.isTokenExpired(claim)) {
            JwtException tokenOver = new JwtException("token已过期");
            resolver.resolveException(request, response, null, tokenOver);
            return;
        }
        if (!jwtUtil.isLoginList(jwt)) {
            JwtException tokenOver = new JwtException("token已注销");
            resolver.resolveException(request, response, null, tokenOver);
            return;
        }
        // Date expiration = claim.getExpiration();
        log.info("JWT到期时间 = {}", DateUtil.formatDateTime(claim.getExpiration()));


        log.info("用户-{}，正在校验JWT！", username);

        // response.setHeader(jwtUtils.getHeader(), "12345678900000000");
        // 获取用户的权限等信息
        SysUser sysUser = sysUserService.findByUsername(username);
        UsernamePasswordAuthenticationToken token
                = new UsernamePasswordAuthenticationToken(username, null, customUserDetailsService.getUserAuthority(sysUser.getId()));
        log.info("UsernamePasswordAuthenticationToken={}", token);
        SecurityContextHolder.getContext().setAuthentication(token);

        chain.doFilter(request, response);
    }
}
